package com.lagou.common.zk;

import com.alibaba.druid.pool.DruidDataSource;
import com.lagou.common.util.DataBaseConfig;
import com.lagou.common.util.JSONSerializer;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.zookeeper.CreateMode;

import javax.sql.DataSource;

public class ConfigCenter {

    private static final String SERVICE_PATH = "/rpc-zookeeper/config/database";
    private static DruidDataSource dataSource;

    private ConfigCenter() {

    }

    public static void registerConfig(DataBaseConfig config) throws Exception {

        NodeCache cache = new NodeCache(ZooKeeperHelper.getClient(), SERVICE_PATH, false);
        cache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                initDataSource();
                System.out.println("DataSource 已重新初始化");
            }
        });
        try {
            cache.start(true);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);
        }

        System.out.println("DataSource Config 已监听成功");

        JSONSerializer serializer = new JSONSerializer();
        byte[] data = serializer.serialize(config);
        ZooKeeperHelper.createNode(SERVICE_PATH, data, CreateMode.EPHEMERAL);

        System.out.println("DataSource Config 已注册成功");
    }

    public static DataBaseConfig getConfig() throws Exception {

        JSONSerializer serializer = new JSONSerializer();
        byte[] data = ZooKeeperHelper.getData(SERVICE_PATH);
        DataBaseConfig config = serializer.deserialize(DataBaseConfig.class, data);

        return config;
    }

    public static void updateConfig(DataBaseConfig config) throws Exception {

        JSONSerializer serializer = new JSONSerializer();
        byte[] data = serializer.serialize(config);
        ZooKeeperHelper.setData(SERVICE_PATH, data);

        System.out.println("DataSource Config 已设置成功");
    }

    public static DataSource getDataSource() throws Exception {
        if (dataSource == null) {
            initDataSource();
        }
        return dataSource;
    }

    private static void initDataSource() throws Exception {
        DataBaseConfig config = ConfigCenter.getConfig();
        createDataSource(config.getDriverClassName(),
                config.getUrl(),
                config.getUsername(),
                config.getPassword());
        System.out.println("配置信息已初始化");
    }

    private static void createDataSource(String driverClassName,
                                         String url,
                                         String username,
                                         String password) {
        dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setInitialSize(5);
        dataSource.setMaxActive(20);
        dataSource.setMaxWait(60000);
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        dataSource.setMinEvictableIdleTimeMillis(300000);
        dataSource.setValidationQuery("SELECT 1 FROM DUAL");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);
        dataSource.setPoolPreparedStatements(false);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
        dataSource.setConnectionProperties("druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000");
    }
}
